package cms.simmytech.dialect;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.thymeleaf.templatemode.TemplateMode;

public class PageCustomDialect extends AbstractElementTagProcessor {

	Log log = LogFactory.getLog(RoleCustomDialect.class);

	private static final String TAG_NAME = "page";

	private static final int PRECEDENCE = 1000;

	private HttpServletRequest request;

	private boolean useSSL;

	private Map<String, String> queryMap = new HashMap<String, String>();

	public PageCustomDialect(final String dialectPrefix, HttpServletRequest request, boolean useSSL) {
		super(TemplateMode.HTML, // 此处理器将仅应用于HTML模式
		        dialectPrefix, // 要应用于名称的匹配前缀
		        TAG_NAME, // 标签名称：匹配此名称的特定标签
		        true, // 没有应用于标签名的前缀
		        null, // 无属性名称：将通过标签名称匹配
		        false, // 没有要应用于属性名称的前缀
		        PRECEDENCE// 优先(内部方言自己的优先
		);
		this.request = request;
		this.useSSL = useSSL;
	}

	@Override
	protected void doProcess(ITemplateContext context, IProcessableElementTag tag, IElementTagStructureHandler structureHandler) {
		String currentPageStr = "${pageInfo.pageNum}";
		String totalPageStr = "${pageInfo.total}";
		String pageSizeStr = "${pageInfo.pageSize}";
		String urlStr = request.getRequestURL().toString();
		if (useSSL&&urlStr.indexOf("http://")>-1) {
			urlStr = urlStr.replace("http://", "https://");
		}else if(!useSSL&&urlStr.indexOf("https://")>-1){
			urlStr=urlStr.replace("https://","http://");
		}
		String queryStr = request.getQueryString();
		if (!StringUtils.isEmpty(currentPageStr) && !StringUtils.isEmpty(totalPageStr) && !StringUtils.isEmpty(pageSizeStr)) {
			currentPageStr = getExpressionValue(context, currentPageStr).toString();
			totalPageStr = getExpressionValue(context, totalPageStr).toString();
			pageSizeStr = getExpressionValue(context, pageSizeStr).toString();
			queryStr = checkNull(queryStr);
			int currentPage = Integer.valueOf(currentPageStr);
			int totalPage = Integer.valueOf(totalPageStr);
			int pageSize = Integer.valueOf(pageSizeStr);
			int lastPage = doLastPage(pageSize, totalPage);
//			if (totalPage > pageSize) {

			IModelFactory modelFactory = context.getModelFactory();
			IModel model = modelFactory.createModel();
			model.add(modelFactory.createOpenElementTag("div class='card-footer clearfix'"));

			model.add(modelFactory.createOpenElementTag("div class='float-left' style='color: #676a6c;font-size: 14px;margin-top: 5px;'"));
			model.add(modelFactory.createOpenElementTag("span"));
			model.add(modelFactory.createText("当前第" + currentPage + "页，共" + lastPage + "页" + totalPage + "条数据，每页"));
			model.add(modelFactory
			        .createOpenElementTag("select  style='width: initial;' class='custom-select custom-select-sm ' onchange='page(this)'"));
			model.add(modelFactory.createOpenElementTag("option value='" + doLink(urlStr, queryStr + "&pageSize=5", currentPage) + "' "
			        + (pageSize == 5 ? "selected='selected'" : "")));
			model.add(modelFactory.createText("5"));
			model.add(modelFactory.createCloseElementTag("option"));
			model.add(modelFactory.createOpenElementTag("option value='" + doLink(urlStr, queryStr + "&pageSize=10", currentPage) + "' "
			        + (pageSize == 10 ? "selected='selected'" : "")));
			model.add(modelFactory.createText("10"));
			model.add(modelFactory.createCloseElementTag("option"));
			model.add(modelFactory.createOpenElementTag("option value='" + doLink(urlStr, queryStr + "&pageSize=15", currentPage) + "' "
			        + (pageSize == 15 ? "selected='selected'" : "")));
			model.add(modelFactory.createText("15"));
			model.add(modelFactory.createCloseElementTag("option"));
			model.add(modelFactory.createOpenElementTag("option value='" + doLink(urlStr, queryStr + "&pageSize=20", currentPage) + "' "
			        + (pageSize == 20 ? "selected='selected'" : "")));
			model.add(modelFactory.createText("20"));
			model.add(modelFactory.createCloseElementTag("option"));
			model.add(modelFactory.createOpenElementTag("option value='" + doLink(urlStr, queryStr + "&pageSize=25", currentPage) + "' "
			        + (pageSize == 25 ? "selected='selected'" : "")));
			model.add(modelFactory.createText("25"));
			model.add(modelFactory.createCloseElementTag("option"));
			model.add(modelFactory.createOpenElementTag("option value='" + doLink(urlStr, queryStr + "&pageSize=30", currentPage) + "' "
			        + (pageSize == 30 ? "selected='selected'" : "")));
			model.add(modelFactory.createText("30"));
			model.add(modelFactory.createCloseElementTag("option"));
			model.add(modelFactory.createCloseElementTag("select"));
			model.add(modelFactory.createText("条数据"));
			model.add(modelFactory.createCloseElementTag("span"));
			model.add(modelFactory.createOpenElementTag("script"));
			model.add(modelFactory.createText("function page(obj) {window.location.href = $(obj).val();}"));
			model.add(modelFactory.createCloseElementTag("script"));
			model.add(modelFactory.createCloseElementTag("div"));
			if (queryStr == null || queryStr.indexOf("pageSize=") < -1) {
				queryStr += "&pageSize=" + pageSize;
			}
			model.add(modelFactory.createOpenElementTag("ul class='pagination pagination-sm m-0 float-right'"));
			model.add(modelFactory.createOpenElementTag("li class='page-item'"));
			model.add(modelFactory.createOpenElementTag(String.format("a class='page-link' href='%s'", doLink(urlStr, queryStr, 1))));
			model.add(modelFactory.createText("首页"));
			model.add(modelFactory.createCloseElementTag("a"));
			model.add(modelFactory.createCloseElementTag("li"));

			model.add(modelFactory.createOpenElementTag("li class='page-item'"));
			model.add(modelFactory.createOpenElementTag(String.format("a class='page-link' href='%s'",
			                                                          doLink(urlStr, queryStr, currentPage - 1 < 1 ? 1 : currentPage - 1))));
			model.add(modelFactory.createText("&laquo;"));
			model.add(modelFactory.createCloseElementTag("a"));
			model.add(modelFactory.createCloseElementTag("li"));
			int page = currentPage > 0 ? currentPage : 1;
			if (currentPage - 2 > 0) {
				page = currentPage - 2;
			} else {
				page = 1;
			}
			int count = 0;
			for (int i = page; i <= lastPage; i++) {
				model.add(modelFactory.createOpenElementTag("li class='page-item " + (currentPage == i ? "active" : "") + "'"));
				model.add(modelFactory.createOpenElementTag(String.format("a class='page-link' href='%s'", doLink(urlStr, queryStr, i))));
				model.add(modelFactory.createText(i + ""));
				model.add(modelFactory.createCloseElementTag("a"));
				model.add(modelFactory.createCloseElementTag("li"));
				count = count + 1;
				if (count >= 5) {
					break;
				}
			}

			model.add(modelFactory.createOpenElementTag("li class='page-item'"));
			model.add(modelFactory.createOpenElementTag(String
			        .format("a class='page-link' href='%s'", doLink(urlStr, queryStr, currentPage + 1 < lastPage ? currentPage + 1 : lastPage))));
			model.add(modelFactory.createText("&raquo;"));
			model.add(modelFactory.createCloseElementTag("a"));
			model.add(modelFactory.createCloseElementTag("li"));

			model.add(modelFactory.createOpenElementTag("li class='page-item'"));
			model.add(modelFactory.createOpenElementTag(String.format("a class='page-link' href='%s'", doLink(urlStr, queryStr, lastPage))));
			model.add(modelFactory.createText("末页"));
			model.add(modelFactory.createCloseElementTag("a"));
			model.add(modelFactory.createCloseElementTag("li"));
			/*
			 * if (currentPage > 1) { model.add(modelFactory.
			 * createOpenElementTag("li class='page-item'"));
			 * model.add(modelFactory.createOpenElementTag(
			 * String.format("a class='page-link' href='%s'", doLink(urlStr,
			 * queryStr, 1)))); model.add(modelFactory.createText("首页"));
			 * model.add(modelFactory.createCloseElementTag("a"));
			 * model.add(modelFactory.createCloseElementTag("li"));
			 * model.add(modelFactory.
			 * createOpenElementTag("li class='page-item'"));
			 * model.add(modelFactory.createOpenElementTag(
			 * String.format("a class='page-link' href='%s'", doLink(urlStr,
			 * queryStr, currentPage-1))));
			 * model.add(modelFactory.createText("&laquo;"));
			 * model.add(modelFactory.createCloseElementTag("a"));
			 * model.add(modelFactory.createCloseElementTag("li"));
			 * model.add(modelFactory.
			 * createOpenElementTag("li class='page-item'"));
			 * model.add(modelFactory.createOpenElementTag(
			 * String.format("a class='page-link' href='%s'", doLink(urlStr,
			 * queryStr, currentPage-1))));
			 * model.add(modelFactory.createText((currentPage - 1) + ""));
			 * model.add(modelFactory.createCloseElementTag("a"));
			 * model.add(modelFactory.createCloseElementTag("li")); }
			 * model.add(modelFactory.
			 * createOpenElementTag("li class='page-item'"));
			 * model.add(modelFactory.createOpenElementTag(
			 * String.format("a class='page-link' href='%s'", doLink(urlStr,
			 * queryStr, currentPage))));
			 * model.add(modelFactory.createText(currentPageStr));
			 * model.add(modelFactory.createCloseElementTag("a"));
			 * model.add(modelFactory.createCloseElementTag("li")); if
			 * ((currentPage + 1) <= lastPage) { model.add(modelFactory.
			 * createOpenElementTag("li class='page-item'"));
			 * model.add(modelFactory.createOpenElementTag(
			 * String.format("a class='page-link' href='%s'", doLink(urlStr,
			 * queryStr, currentPage+1))));
			 * model.add(modelFactory.createText((currentPage + 1) + ""));
			 * model.add(modelFactory.createCloseElementTag("a"));
			 * model.add(modelFactory.createCloseElementTag("li"));
			 * model.add(modelFactory.
			 * createOpenElementTag("li class='page-item'"));
			 * model.add(modelFactory.createOpenElementTag(
			 * String.format("a class='page-link' href='%s'", doLink(urlStr,
			 * queryStr, currentPage+1))));
			 * model.add(modelFactory.createText("&raquo;"));
			 * model.add(modelFactory.createCloseElementTag("a"));
			 * model.add(modelFactory.createCloseElementTag("li"));
			 * model.add(modelFactory.
			 * createOpenElementTag("li class='page-item'"));
			 * model.add(modelFactory.createOpenElementTag(
			 * String.format("a class='page-link' href='%s'", doLink(urlStr,
			 * queryStr, lastPage)))); model.add(modelFactory.createText("末页"));
			 * model.add(modelFactory.createCloseElementTag("a"));
			 * model.add(modelFactory.createCloseElementTag("li")); }
			 */

			model.add(modelFactory.createCloseElementTag("ul"));
			model.add(modelFactory.createCloseElementTag("div"));
			structureHandler.replaceWith(model, false);
		}
//		}
	}

	private String doLink(String url, String query, int pageNum) {
		queryMap = new HashMap<>();
		initMap(query);
		return fullLink(url, pageNum);
	}

	private String fullLink(String url, int pageNum) {
		queryMap.put("currentPage", pageNum + "");
		StringBuffer sb = new StringBuffer(url);
		for (String key : queryMap.keySet()) {
			if (sb.indexOf("?") == -1) {
				sb.append("?");
			} else {
				sb.append("&");
			}
			sb.append(key);
			sb.append("=");
			sb.append(queryMap.get(key));
		}
		return sb.toString();
	}

	private void initMap(String query) {
		if (!StringUtils.isEmpty(query)) {
			String[] params = query.split("&");
			for (String param : params) {
				String[] keyValues = param.split("=");
				if (keyValues != null && keyValues.length == 2) {
					queryMap.put(keyValues[0], keyValues[1]);
				}
			}
		}
	}

	private int doLastPage(int pageSize, int totalCount) {
		if (totalCount <= pageSize) {
			return 1;
		}
		int tempPage = totalCount / pageSize;
		if (totalCount % pageSize == 0) {
			return tempPage;
		} else {
			return tempPage + 1;
		}
	}

	private String checkNull(Object temp) {
		if (null == temp) {
			return null;
		}
		return temp.toString();
	}

	private Object getExpressionValue(ITemplateContext iTemplateContext, String expressionString) {
		final IEngineConfiguration configuration = iTemplateContext.getConfiguration();
		final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
		// 解析expression
		final IStandardExpression expression = parser.parseExpression(iTemplateContext, expressionString);
		// 获取expression的执行结果
		return expression.execute(iTemplateContext);
	}

}
